﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using System.ComponentModel;
using System.Data.SqlTypes;

namespace TradingAppDal
{
    public class EntityDal : DataAccess
    {
        public SqlInt64 Entity_ID { get; set; }
        public string Entity_Name { get; set; }
        public SqlDateTime Entities_FromDate { get; set; }
        public SqlDateTime Entities_ToDate { get; set; }
        public SqlDateTime Entities_MaxDate { get; set; }
        public SqlDateTime Entities_Requested { get; set; }
        public SqlDateTime Entities_InQue { get; set; }
        public SqlDateTime Entities_InProcess { get; set; }
        public SqlDateTime Entities_Processed { get; set; }
        public SqlInt64 Process_ID { get; set; }
        public string ReportingName
        {
            get
            {
                return Entity_Name + " (Process ID -" + Process_ID.ToString() + ")";
            }
        }
        public string Entities_InQueStr
        {
            get
            {
                return TradingAppUtil.GetDateString(Entities_InQue);
            }
        }
        public string Entities_InProcessStr
        {
            get
            {
                return TradingAppUtil.GetDateString(Entities_InProcess);
            }
        }
        public string Entities_ProcessedStr
        {
            get
            {
                return TradingAppUtil.GetDateString(Entities_Processed);
            }
        }
        public bool IsProcessingCompleted()
        {
            bool isCompleted = true;
            if (Securities != null && Securities.Count > 0)
            {
                isCompleted = !Securities.Exists(p => p.IsProcessingCompleted == false);
            }
            return isCompleted;
        }
        public List<SecurityDal> Securities { get; set; }
        public List<EntityDal> GetEntities(EntityType oEntityType)
        {
            List<EntityDal> lst = new List<EntityDal>();
            try
            {
                string get_SP_Name = GetFetchSPName(oEntityType);
                SqlCommand cmd = GetSPCommand(get_SP_Name);
                SqlDataReader reader = cmd.ExecuteReader();
                while (reader.Read())
                {
                    EntityDal oEntityDal = new EntityDal();
                    oEntityDal.Entity_Name = ToString(reader["Entity_Name"]);
                    oEntityDal.Process_ID = ToSqlInt64(reader["Process_ID"]);
                    oEntityDal.Entities_FromDate = ToSqlDateTime(reader["Entities_FromDate"]);
                    oEntityDal.Entities_ToDate = ToSqlDateTime(reader["Entities_ToDate"]);
                    oEntityDal.Entities_MaxDate = ToSqlDateTime(reader["Entities_MaxDate"]);
                    oEntityDal.Entities_Requested = ToSqlDateTime(reader["Entities_Requested"]);

                    oEntityDal.Entities_InQue = ToSqlDateTime(reader["Entities_InQue"]);
                    oEntityDal.Entities_InProcess = ToSqlDateTime(reader["Entities_InProcess"]);
                    oEntityDal.Entities_Processed = ToSqlDateTime(reader["Entities_Processed"]);

                    lst.Add(oEntityDal);
                }
                reader.Close();
                reader = null;

            }
            finally
            {
                CloseConnection();
            }

            return lst;
        }
        public EntityDal GetEntityByProcessID(long ProcessID)
        {
            EntityDal oEntityDal = new EntityDal();
            SqlCommand cmd = GetSPCommand("get_Entity_ByProcessID");
            try
            {
                cmd.Parameters.Add(new SqlParameter("@Process_ID", ProcessID));
                SqlDataReader reader = cmd.ExecuteReader();
                if (reader.Read())
                {
                    oEntityDal.Entity_Name = ToString(reader["Entity_Name"]);
                    oEntityDal.Process_ID = ToSqlInt64(reader["Process_ID"]);
                    oEntityDal.Entities_FromDate = ToSqlDateTime(reader["Entities_FromDate"]);
                    oEntityDal.Entities_ToDate = ToSqlDateTime(reader["Entities_ToDate"]);
                    oEntityDal.Entities_MaxDate = ToSqlDateTime(reader["Entities_MaxDate"]);
                    oEntityDal.Entities_Requested = ToSqlDateTime(reader["Entities_Requested"]);

                    oEntityDal.Entities_InQue = ToSqlDateTime(reader["Entities_InQue"]);
                    oEntityDal.Entities_InProcess = ToSqlDateTime(reader["Entities_InProcess"]);
                    oEntityDal.Entities_Processed = ToSqlDateTime(reader["Entities_Processed"]);

                }
                reader.Close();
                reader = null;

            }
            finally
            {
                CloseConnection(cmd.Connection);
            }

            return oEntityDal;
        }
        public SqlInt32 UpdateEntity(long ProcessID, EntityType oEntityType)
        {
            SqlInt32 iError = 0;
            string update_SP_Name = GetUpdateSPName(oEntityType);
            SqlCommand cmd = GetSPCommand(update_SP_Name);
                
            try
            {
                cmd.Parameters.Add(new SqlParameter("@Process_ID", ProcessID));
                cmd.ExecuteNonQuery();

            }
            finally
            {
                CloseConnection(cmd.Connection);
            }

            return iError;
        }
        public SqlInt32 ReprocessEntity(long ProcessID)
        {
            SqlInt32 iError = 0;
            SqlCommand cmd = GetSPCommand("set_Reprocess_Entity");
            try
            {
                cmd.Parameters.Add(new SqlParameter("@Process_ID", ProcessID));
                cmd.ExecuteNonQuery();
            }
            finally
            {
                CloseConnection(cmd.Connection);
            }
            return iError;
        }

        private string GetUpdateSPName(EntityType oEntityType)
        {
            string sp_Name = "";
            switch (oEntityType)
            {
                case EntityType.InQueue:
                    sp_Name = "sp_Update_Entities_InQue ";
                    break;
                case EntityType.InProcess:
                    sp_Name = "sp_Update_Entities_InProcess ";
                    break;
                case EntityType.Processed:
                    sp_Name = "sp_Update_Entities_Processed";
                    break;
            }
            return sp_Name;
        }

        private string GetFetchSPName(EntityType oEntityType)
        {
            string sp_Name = "";
            switch (oEntityType)
            {
                case EntityType.InQueue:
                    sp_Name = "get_Entities_InQueue";
                    break;
                case EntityType.InProcess:
                    sp_Name = "get_Entities_InProcess";
                    break;
                case EntityType.Processed:
                    sp_Name = "get_Entities_Processed";
                    break;
                case EntityType.ToProcess:
                    sp_Name = "get_Entities_ToProcess";
                    break;
                case EntityType.All:
                    sp_Name = "get_Entities_All";
                    break;
            }
            return sp_Name;
        }

    }
    public enum EntityType
    {
        ToProcess,
        InProcess,
        Processed,
        InQueue,
        All
    }
    public class DataAccess
    {
        [NonSerialized]
        protected SqlConnection connection;
        [NonSerialized]
        protected SqlCommand command;
        public static SqlDouble ToSqlDouble(Object ID)
        {
            SqlDouble siID;

            if (ID == DBNull.Value)
            {
                siID = SqlDouble.Null;
            }
            else
            {
                if (ID is SqlDouble)
                    return (SqlDouble)ID;
                siID = new SqlDouble((double)ID);
            }

            return siID;
        }

        public static SqlBoolean ToSqlBoolean(Object ID)
        {
            SqlBoolean siID;

            if (ID == DBNull.Value)
            {
                siID = SqlBoolean.Null;
            }
            else
            {
                if (ID is SqlBoolean)
                    return (SqlBoolean)ID;
                siID = new SqlBoolean((bool)ID);
            }

            return siID;
        }

        public static SqlInt32 ToSqlInt32(Object ID)
        {
            SqlInt32 siID;

            if (ID == DBNull.Value)
            {
                siID = SqlInt32.Null;
            }
            else
            {
                if (ID is SqlInt32)
                    return (SqlInt32)ID;
                siID = new SqlInt32(Convert.ToInt32(ID));
            }

            return siID;
        }
        public static SqlInt64 ToSqlInt64(Object ID)
        {
            SqlInt64 siID;

            if (ID == DBNull.Value)
            {
                siID = SqlInt64.Null;
            }
            else
            {
                if (ID is SqlInt64)
                    return (SqlInt64)ID;
                siID = new SqlInt64(Convert.ToInt64(ID));
            }

            return siID;
        }
        public static Int64? ToInt64(Object ID)
        {
            Int64? siID;

            if (ID == DBNull.Value)
            {
                siID = null;
            }
            else
            {
                if (ID is Int64)
                    return (Int64)ID;
                siID = (Int64?)(Convert.ToInt64(ID));
            }

            return siID;
        }
        public static Int32? ToInt32(Object ID)
        {
            Int32? siID;

            if (ID == DBNull.Value)
            {
                siID = null;
            }
            else
            {
                if (ID is Int32)
                    return (Int32)ID;
                siID = (Int32?)(Convert.ToInt64(ID));
            }

            return siID;
        }

        public static SqlGuid ToSqlGuid(Object ID)
        {
            SqlGuid siID;

            if (ID == DBNull.Value)
            {
                siID = SqlGuid.Null;
            }
            else
            {
                if (ID is SqlGuid)
                    return (SqlGuid)ID;
                siID = new SqlGuid(new Guid(ID.ToString()));
            }

            return siID;
        }

        public static SqlDecimal ToSqlDecimal(Object ID)
        {
            SqlDecimal siID;

            if (ID == DBNull.Value)
            {
                siID = SqlDecimal.Null;
            }
            else
            {
                if (ID is SqlDecimal)
                    return (SqlDecimal)ID;
                siID = new SqlDecimal(Convert.ToDecimal(ID));
            }

            return siID;
        }
        public static Decimal? ToDecimal(Object ID)
        {
            Decimal? siID;

            if (ID == DBNull.Value)
            {
                siID = null;
            }
            else
            {
                if (ID is Decimal)
                    return (Decimal)ID;
                siID = (Decimal?)(Convert.ToDecimal(ID));
            }

            return siID;
        }

        public static SqlMoney ToSqlMoney(Object s)
        {
            SqlMoney siMoney;

            if (s == DBNull.Value)
            {
                siMoney = SqlMoney.Null;
            }
            else
            {
                if (s is SqlMoney)
                    return (SqlMoney)s;
                siMoney = new SqlMoney(Convert.ToDecimal(s));
            }

            return siMoney;
        }

        public static SqlDateTime ToSqlDateTime(Object s)
        {
            SqlDateTime sDateTime;

            if (s == DBNull.Value)
            {
                sDateTime = SqlDateTime.Null;
            }
            else
            {
                if (s is SqlDateTime)
                    return (SqlDateTime)s;
                sDateTime = new SqlDateTime(Convert.ToDateTime(s));
            }

            return sDateTime;
        }
        public static DateTime? ToDateTime(Object s)
        {
            DateTime? sDateTime;

            if (s == DBNull.Value)
            {
                sDateTime = null;
            }
            else
            {
                if (s is DateTime)
                    return (DateTime)s;
                sDateTime = (DateTime?)(Convert.ToDateTime(s));
            }

            return sDateTime;
        }

        public static string ToString(Object s)
        {

            if (s == DBNull.Value)
            {
                return String.Empty;
            }
            else
            {
                return (string)s;
            }
        }
        public SqlCommand GetSPCommand(string storedProcedure)
        {
            SqlConnection connection = new SqlConnection(TradingAppSettings.DBConnectionStr);
            SqlCommand command = connection.CreateCommand();
            command.CommandType = CommandType.StoredProcedure;
            command.CommandText = storedProcedure;
            //command.CommandTimeout  = ;
            connection.Open();
            return command;
        }
        public void CloseConnection()
        {
            if (connection != null && connection.State == ConnectionState.Open)
            {
                connection.Close();
                connection.Dispose();
            }
        }
        public void CloseConnection(SqlConnection connection)
        {
            if (connection != null && connection.State == ConnectionState.Open)
            {
                connection.Close();
                connection.Dispose();
            }
        }
    }

}
